package com.csust.automaticteach.service.impl;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csust.automaticteach.app.student.learnchat.LearnChatAppFacade;
import com.csust.automaticteach.app.student.learnchat.OnlineLearnApp;
import com.csust.automaticteach.exception.BusinessException;
import com.csust.automaticteach.exception.ErrorCode;
import com.csust.automaticteach.exception.ThrowUtils;
import com.csust.automaticteach.model.dto.learnchat.LearnChatQueryRequest;
import com.csust.automaticteach.model.entity.LearnChat;
import com.csust.automaticteach.model.entity.User;
import com.csust.automaticteach.model.enums.BizTypeEnum;
import com.csust.automaticteach.model.enums.ChatHistoryMessageTypeEnum;
import com.csust.automaticteach.model.enums.ChatSchemaEnum;
import com.csust.automaticteach.service.ChatHistoryService;
import com.csust.automaticteach.service.LearnChatService;
import com.csust.automaticteach.mapper.LearnChatMapper;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Flux;

import java.io.Serializable;
import java.util.Date;

import static com.csust.automaticteach.constant.OrderConstant.ASC;

/**
* @author 钰玟
* @ description 针对表【t_learn_chat(学习聊天表)】的数据库操作Service实现
* @ createDate 2025-09-27 13:36:34
*/
@Service
public class LearnChatServiceImpl extends ServiceImpl<LearnChatMapper, LearnChat>
    implements LearnChatService{

    private final ChatHistoryService chatHistoryService;
    private final LearnChatAppFacade learnChatAppFacade;

    public LearnChatServiceImpl(@Lazy ChatHistoryService chatHistoryService,LearnChatAppFacade learnChatAppFacade) {
        this.chatHistoryService = chatHistoryService;
        this.learnChatAppFacade = learnChatAppFacade;
    }

    /**
     *  聊天生成代码
     * @param learnChatId 聊天ID
     * @param message 用户输入
     * @param model 模型
     * @param  promptId 提示ID
     * @param loginUser 登录用户
     * @param chatSchema 聊天模式
     * @return Flux<String>
     */
    @Override
    public Flux<String> chatToLearn(Long learnChatId, String message, String model, String promptId, User loginUser, ChatSchemaEnum chatSchema) {
        // 1. 参数校验
        ThrowUtils.throwIf(learnChatId == null || learnChatId <= 0, ErrorCode.PARAMS_ERROR, "聊天ID 不能为空");
        ThrowUtils.throwIf(StrUtil.isBlank(message), ErrorCode.PARAMS_ERROR, "用户消息不能为空");
        // 2. 查询聊天会话信息
        LearnChat learnChat = this.getById(learnChatId);
        ThrowUtils.throwIf(learnChat == null, ErrorCode.NOT_FOUND_ERROR, "聊天会话不存在");
        // 3. 验证用户是否有权限访问该应用，仅本人可以聊天
        if (!learnChat.getUserId().equals(loginUser.getId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权限访问该来哦天会话");
        }
        // 4. 调用 AI 回复
        Flux<String> stringFlux = learnChatAppFacade.chatToLearn(message,model,learnChatId,promptId,chatSchema);
        chatHistoryService.addChatMessage(learnChatId, BizTypeEnum.CHAT_LEARN.getValue(), message, ChatHistoryMessageTypeEnum.USER.getValue(), loginUser.getId());
        StringBuilder sb = new StringBuilder();
        // 5. 插入聊天记录 todo
        return stringFlux.doOnNext(sb::append)
                        .doOnComplete(()->{
                            String content = sb.toString();
                            String messageType = ChatHistoryMessageTypeEnum.AI.getValue();
                            chatHistoryService.addChatMessage(learnChatId, BizTypeEnum.CHAT_LEARN.getValue(), content, messageType, loginUser.getId());
                        });
    }

    /**
     *  获取查询包装类
     * @param learnChatQueryRequest 查询请求
     * @return 查询包装类
     */
    @Override
    public QueryWrapper<LearnChat> getQueryWrapper(LearnChatQueryRequest learnChatQueryRequest) {
        if (learnChatQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        Long id = learnChatQueryRequest.getId();
        String title = learnChatQueryRequest.getTitle();
        String initPrompt = learnChatQueryRequest.getInitPrompt();
        Long userId = learnChatQueryRequest.getUserId();
        String sortField = learnChatQueryRequest.getSortField();
        String sortOrder = learnChatQueryRequest.getSortOrder();
        Date lastCreateTime = learnChatQueryRequest.getLastCreateTime();
        // 创建查询条件
        QueryWrapper<LearnChat> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjUtil.isNotNull(id),"id", id)
                .like(StrUtil.isNotBlank(title),"title", title)
                .like(StrUtil.isNotBlank(initPrompt),"initPrompt", initPrompt)
                .eq(ObjUtil.isNotNull(userId),"userId", userId);
        // 游标查询逻辑 - 只使用 createTime 作为游标
        if (lastCreateTime != null) {
            queryWrapper.lt("createTime", lastCreateTime);
        }
        // 排序
        if (StrUtil.isNotBlank(sortField)) {
            queryWrapper.orderBy(StrUtil.isNotBlank(sortField), ASC.equals(sortOrder),sortField);
        } else {
            // 默认按创建时间降序排列
            queryWrapper.orderBy(true,false,"createTime");
        }
        return queryWrapper;
    }

    @Override
    @Transactional
    public boolean removeById(Serializable id) {
        Long learnChatId = (Long) id;
        if (learnChatId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        //先删聊天记录
        try {
            BizTypeEnum bizTypeEnum = BizTypeEnum.CHAT_LEARN;
            boolean deleted = chatHistoryService.deleteChatMessage(learnChatId, bizTypeEnum.getValue());
        } catch (Exception e) {
            log.error("删除会话聊天历史失败" + e.getMessage());
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除会话失败");
        }
        return super.removeById(id);
    }
}




